﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DataModel;
using BindableDataGrid.Data;
using System.ServiceModel.Channels;
using A_DirectDBAccess.Services.Reporting.DirectDB;

namespace A_DirectDBAccess
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            DDBAC.ExecuteQueryCompleted += new EventHandler<Services.Reporting.DirectDB.ExecuteQueryCompletedEventArgs>(DDBAC_ExecuteQueryCompleted);
            DDBAC.ExecuteStatementCompleted += new EventHandler<Services.Reporting.DirectDB.ExecuteStatementCompletedEventArgs>(DDBAC_ExecuteStatementCompleted);
            DDBAC.LoadAutoCompleteCompleted += new EventHandler<Services.Reporting.DirectDB.LoadAutoCompleteCompletedEventArgs>(DDBAC_LoadAutoCompleteCompleted);
            DDBAC.LoadAutoCompleteAsync();
        }

        void DDBAC_ExecuteStatementCompleted(object sender, Services.Reporting.DirectDB.ExecuteStatementCompletedEventArgs e)
        {
            try
            {
                LogResult(e.Result);
            }
            catch
            {
            }
            ExecuteNext();
        }

        void DDBAC_LoadAutoCompleteCompleted(object sender, Services.Reporting.DirectDB.LoadAutoCompleteCompletedEventArgs e)
        {
            SQLQuery.ItemsSource = e.Result;
        }

        DateTime Last = DateTime.Now.Subtract(new TimeSpan(0,0,10));
        void LogResult(string Result)
        {
            if (DateTime.Now.Subtract(Last).TotalSeconds >= 1)
            {
                Last = DateTime.Now;
                StatementResults.Items.Insert(0, DateTime.Now.ToLongTimeString());
            }
            StatementResults.Items.Insert(0, Result);
        }

        private void ExecuteQuery_Click(object sender, RoutedEventArgs e)
        {
            DDBAC.ExecuteQueryAsync(SQLQuery.Text);
        }

        void DDBAC_ExecuteQueryCompleted(object sender, Services.Reporting.DirectDB.ExecuteQueryCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                MessageBox.Show(e.Error.GetBaseException().Message);
                return;
            }
            var hd = e.Result.Headers;
            var data = e.Result.Rows;
            DataTable dt = new DataTable("MyDataTable");
            for (int i = 0; i < hd.Count; i++)
            {
                DataColumn DC = new DataColumn("COL" + i.ToString());
                DC.Caption = hd[i];

                DC.DataType = data.Select((r) => r.Values[i]).Where((v) => v != null).DefaultIfEmpty("").First().GetType();
                DC.AllowResize = true;
                DC.AllowSort = true;
                DC.AllowReorder = true;
                DC.ReadOnly = true;
                dt.Columns.Add(DC);
            }
            for (int i = 0; i < data.Count; i++)
            {
                DataRow dr = new DataRow();
                for (int x = 0; x < hd.Count; x++)
                {
                    if (data[i].Values[x] == null)
                    {
                        dr["COL" + x.ToString()] = "";
                    }
                    else
                    {
                        dr["COL" + x.ToString()] = data[i].Values[x];
                    }
                    
                }
                dt.Rows.Add(dr);
            }
            QueryResults.DataSource = dt;
            QueryResults.DataBind();
        }




        DirectDBAccessClient DDBAC = ServiceConfig.NewDirectDBAccessClient();


        Queue<string> StatementQueue = new Queue<string>();
        void ExecuteNext()
        {
            if (StatementQueue.Count != 0)
            {
                DDBAC.ExecuteStatementAsync(StatementQueue.Dequeue());
            }
            else
            {
                LogResult("--Execution Ended--");
            }
        }
        private void ExecuteStatement_Click(object sender, RoutedEventArgs e)
        {
            foreach (var item in new EnumerableString(SQLStatements.Text))
            {
                StatementQueue.Enqueue(item);
            }
            ExecuteNext();
            LogResult(String.Format("--Execution Started--", DateTime.Now.ToShortTimeString()));
        }

        private void SQLQuery_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                DDBAC.ExecuteQueryAsync(SQLQuery.Text);
            }
        }

        private void CancelStatement_Click(object sender, RoutedEventArgs e)
        {
            StatementQueue.Clear();
        }
    }

    public class EnumerableString:IEnumerable<string>
    {
        string s;
        public EnumerableString(string s)
        {
            this.s = s;
        }

        #region IEnumerable<string> Members

        public IEnumerator<string> GetEnumerator()
        {
            return new EnumeratorString(s);
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }

        #endregion

        public class EnumeratorString:IEnumerator<string>
        {
            string SBase;
            System.IO.StringReader SR;
            string CurrentLine;
            public EnumeratorString(string SBase)
            {
                this.SR = new System.IO.StringReader(SBase);
                this.SBase = SBase;
            }
            #region IEnumerator<string> Members

            public string Current
            {
                get 
                {
                    return CurrentLine;
                }
            }

            #endregion

            #region IDisposable Members

            public void Dispose()
            {
                SR.Dispose();
            }

            #endregion

            #region IEnumerator Members

            object System.Collections.IEnumerator.Current
            {
                get { return this.Current; }
            }

            public bool MoveNext()
            {
                if (SR.Peek() != -1)
                {
                    CurrentLine = SR.ReadLine();
                    return true;
                }
                return false;
            }

            public void Reset()
            {
                this.SR = new System.IO.StringReader(SBase);
            }

            #endregion
        }
    }
}
